﻿using System;
using System.IO.Ports;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        private SerialPort serialPort;

        public Form1()
        {
            InitializeComponent();
            InitializeSerialPortSettings();
            FillPortNames();
            FillBaudRates();
            FillDataBits();
            FillStopBits();
            FillParityOptions();
        }

        private void InitializeSerialPortSettings()
        {
            serialPort = new SerialPort();
            serialPort.DataReceived += new SerialDataReceivedEventHandler(serialPort_DataReceived);
        }

        private void FillPortNames()
        {
            comboBoxPort.Items.Clear();
            string[] ports = SerialPort.GetPortNames();
            foreach (string port in ports)
            {
                comboBoxPort.Items.Add(port);
            }
            if (comboBoxPort.Items.Count > 0)
            {
                comboBoxPort.SelectedIndex = 0;
            }
        }

        private void FillBaudRates()
        {
            comboBoxBaudRate.Items.Clear();
            comboBoxBaudRate.Items.AddRange(new string[] { "9600", "19200", "38400", "57600", "115200" });
            comboBoxBaudRate.SelectedIndex = 4;
        }

        private void FillDataBits()
        {
            comboBoxDataBits.Items.Clear();
            comboBoxDataBits.Items.AddRange(new string[] { "5", "6", "7", "8" });
            comboBoxDataBits.SelectedIndex = 3;
        }

        private void FillStopBits()
        {
            comboBoxStopBits.Items.Clear();
            comboBoxStopBits.Items.AddRange(new string[] { "1", "1.5", "2" });
            comboBoxStopBits.SelectedIndex = 0;
        }

        private void FillParityOptions()
        {
            comboBoxParity.Items.Clear();
            comboBoxParity.Items.AddRange(Enum.GetNames(typeof(Parity)));
            comboBoxParity.SelectedIndex = 0;
        }

        private void buttonOpenClose_Click(object sender, EventArgs e)
        {
            if (serialPort.IsOpen)
            {
                serialPort.Close();
                buttonOpenClose.Text = "打开串口";
            }
            else
            {
                try
                {
                    serialPort.PortName = comboBoxPort.Text;
                    serialPort.BaudRate = int.Parse(comboBoxBaudRate.Text);
                    serialPort.DataBits = int.Parse(comboBoxDataBits.Text);
                    serialPort.StopBits = (StopBits)Enum.Parse(typeof(StopBits), comboBoxStopBits.Text);
                    serialPort.Parity = (Parity)Enum.Parse(typeof(Parity), comboBoxParity.Text);
                    serialPort.Open();
                    buttonOpenClose.Text = "关闭串口";
                }
                catch (Exception ex)
                {
                    MessageBox.Show("打开串口失败: " + ex.Message);
                }
            }
        }

        private void buttonSend_Click(object sender, EventArgs e)
        {
            if (serialPort.IsOpen)
            {
                string dataToSend = textBoxSend.Text;
                try
                {
                    byte[] bytesToSend;
                    if (checkBoxHexSend.Checked)
                    {
                        dataToSend = dataToSend.Replace(" ", "");
                        bytesToSend = new byte[dataToSend.Length / 2];
                        for (int i = 0; i < bytesToSend.Length; i++)
                        {
                            bytesToSend[i] = Convert.ToByte(dataToSend.Substring(i * 2, 2), 16);
                        }
                        serialPort.Write(bytesToSend, 0, bytesToSend.Length);
                        string hexLog = BitConverter.ToString(bytesToSend).Replace("-", " ");
                        AppendLog($"SEND {serialPort.PortName}: {hexLog}");
                    }
                    else
                    {
                        serialPort.Write(dataToSend);
                        AppendLog($"SEND {serialPort.PortName}: {dataToSend}");
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("发送数据失败: " + ex.Message);
                }
            }
            else
            {
                MessageBox.Show("请先打开串口");
            }
        }

        private void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            if (serialPort.IsOpen)
            {
                string receivedData = serialPort.ReadExisting();
                if (checkBoxHexDisplay.Checked)
                {
                    receivedData = BitConverter.ToString(System.Text.Encoding.UTF8.GetBytes(receivedData)).Replace("-", " ");
                }
                AppendLog($"RECV {serialPort.PortName}: {receivedData}");
            }
        }

        private void AppendLog(string message)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new Action(() => richTextBoxLog.AppendText(DateTime.Now + " " + message + Environment.NewLine)));
            }
            else
            {
                richTextBoxLog.AppendText(DateTime.Now + " " + message + Environment.NewLine);
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (serialPort.IsOpen)
            {
                serialPort.Close();
            }
        }
    }
}